package com.gitee.sop.bridge.route;

import com.gitee.sop.gatewaycommon.bean.InstanceDefinition;
import com.gitee.sop.gatewaycommon.route.BaseRegistryListener;
import com.i72.basic.SOAServiceAddress;
import com.i72.basic.SOAServiceCenter;
import com.i72.basic.SOAServiceNode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEvent;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.BiConsumer;

/**
 * @author jiangj
 * @version 1.0.0
 * @ClassName ZKRegisterListener.java
 * @Description TODO
 * @createTime 2022年01月05日 10:02:00
 */
public class ZKRegisterListener extends BaseRegistryListener {

    @Autowired
    private SOAServiceCenter soaServiceCenter;

    private Set<SOAServiceNode> nodeSet = new HashSet<>();

    private final static String OPEN_PLATFORM_CONFIG_KEY = "openPlatform";

    private static Map<String,Integer> serviceNamePlatformMap = new HashMap<>();

    //private static AtomicBoolean init = new AtomicBoolean(true);

    @Override
    public void onEvent(ApplicationEvent applicationEvent) {

        //soaServiceCenter

        Map<String, SOAServiceAddress> soaServiceAddressMap = soaServiceCenter.getServiceAddresses();

        if(soaServiceAddressMap!=null && soaServiceAddressMap.keySet().size()>0){
            Set<SOAServiceNode> currentNodeSet = new HashSet<>();
            soaServiceAddressMap.forEach(new BiConsumer<String, SOAServiceAddress>() {
                @Override
                public void accept(String s, SOAServiceAddress soaServiceAddress) {
                    if(soaServiceAddress.getNodeListMap().keySet().size()<=0){
                        return;
                    }
                    String openPlatform = soaServiceCenter.getConfig(s,OPEN_PLATFORM_CONFIG_KEY);
                    boolean isOpenPlatform = false;
                    if(!StringUtils.isEmpty(openPlatform)){
                        isOpenPlatform = true;
                    }
                    if(isOpenPlatform){

                        soaServiceAddress.getNodeListMap().forEach(new BiConsumer<String, List<SOAServiceNode>>() {
                            @Override
                            public void accept(String nodeType, List<SOAServiceNode> soaServiceNodes) {
                                soaServiceNodes.forEach(i->{
                                    i.setServiceName(s);
                                    serviceNamePlatformMap.put(s,new Integer(openPlatform));
                                    currentNodeSet.add(i);
                                });
                            }
                        });

                    }
                }
            });

            /*
            if(init.get()){
                init.set(false);

                nodeSet.addAll(currentNodeSet);

                nodeSet.forEach(i->{
                    InstanceDefinition instanceDefinition = new InstanceDefinition();
                    instanceDefinition.setInstanceId(i.getServiceName()+"-"+i.getIp());
                    if(i.getIp().contains(":")){
                        String [] address = i.getIp().split(":");
                        instanceDefinition.setIp(address[0]);
                        instanceDefinition.setPort(new Integer(address[1]));
                    }else{
                        instanceDefinition.setIp(i.getIp());
                        instanceDefinition.setPort(80);
                    }
                    instanceDefinition.setServiceId(i.getServiceName());
                    instanceDefinition.setMetadata(new HashMap<>());
                    this.pullRoutes(instanceDefinition);
                });


            }*/

            Set<SOAServiceNode> s1 = new HashSet<>();
            s1.addAll(currentNodeSet);
            s1.removeAll(nodeSet);

                //求差集  假设有集合A和B，所有属于A且不属于B的元素的集合被称为A与B的差集。
                //当前有，之前没有，则新增


            if(s1.size()>0){
                s1.forEach(i->{
                    InstanceDefinition instanceDefinition = new InstanceDefinition();
                    instanceDefinition.setInstanceId(i.getServiceName()+"-"+i.getIp());
                    if(i.getIp().contains(":")){
                        String [] address = i.getIp().split(":");
                        instanceDefinition.setIp(address[0]);
                        instanceDefinition.setPort(new Integer(address[1]));
                    }else{
                        instanceDefinition.setIp(i.getIp());
                        instanceDefinition.setPort(80);
                    }
                    instanceDefinition.setServiceId(i.getServiceName());
                    instanceDefinition.setMetadata(new HashMap<>());
                    instanceDefinition.setApplicationType(serviceNamePlatformMap.get(i.getServiceName()));
                    this.pullRoutes(instanceDefinition);
                });

                nodeSet.addAll(s1);
            }


            Set<SOAServiceNode> s2 = new HashSet<>();
            s2.addAll(nodeSet);
            s2.removeAll(currentNodeSet);
            //求差集  假设有集合A和B，所有属于A且不属于B的元素的集合被称为A与B的差集。
            //之前有，现在没有，则删除

            if(s2.size()>0) {
                //this.removeRoutes("");
                nodeSet.clear();
                nodeSet.addAll(currentNodeSet);
                s2.forEach(i->{
                    if(!currentNodeSet.stream().anyMatch(j->{
                        return j.getServiceName().equals(i.getServiceName());
                    })) {
                        //服务的所有节点都不存在了。即服务下线，此时会执行删除操作
                        this.removeRoutes(i.getServiceName());
                    }
                });
            }
            //nodeSet.removeAll(s2);


        }
    }
}
